AWS SDK for Ruby version2 Released!
こんにちは。望月です。
全国3000万人のAWS SDK for Rubyファンの皆様お待たせしました。本日ついにAWS SDK for RubyのメジャーバージョンアップであるAWS SDK for Ruby 2(以下 SDK v2)がリリースされました。
今までもDeveloper Previewとしてリリースされていましたが、これで正式版となったわけです。今日はインストール方法とバージョン2での新機能、今までのAWS SDK for Ruby(以下SDK v1)との違いなどについて私が気付いた点をまとめたいと思います。
インストール
以前までと同様、Rubygemsによってホストされていますので、gemコマンドでインストールします。ただしgem名はaws-sdk-coreとなっていますので注意して下さい。
$ gem install aws-sdk-core ... $ ruby -r aws-sdk-core -e 'puts Aws::VERSION' 2.0.0
正常にインストールされた場合、バージョン番号が表示されると思います。
新機能
特筆すべきfeatureはほとんどREADMEに書かれているので、それを試してみました。
簡単なページング
APIリクエストに対して大量の結果が返される場合、一度に返される量を制限する必要があります。例えばS3のListObjectsの場合、API上ではtokenとして表現されているので、AWS CLIでは以下のような感じになります。
$ aws s3api list-objects --bucket mochizuki-bucket --profile default --max-items 10 { "NextToken": "None___10", "CommonPrefixes": [], "Contents": [ <10個分のObject> ] } # 前のAPIレスポンスのNextTokenを指定 $ aws s3api list-objects --bucket mochizuki-bucket --profile default --max-items 10 --starting-token None___10 { "NextToken": "None___20", "CommonPrefixes": [], "Contents": [ <10個分のObject> ] }
SDK v1 で記載すると、毎回リクエストの度にmarkerを取得し、パラメータにセットし、APIリクエストを実行する、という必要があり非常に面倒でした。ですが、SDK v2でPageableResponseクラスというものが作成され、そのレスポンスクラスがページング処理のための便利な機能を持っています。実際にコードを見てみましょう。
require 'aws-sdk-core' s3 = Aws::S3::Client.new resp = s3.list_objects(bucket: 'mochizuki-bucket', max_keys: "10") resp.contents.each{ |obj| puysobj[:key] } # 続きがあるかどうかを判定 until resp.last_page? resp = resp.next_page # 次のリソースを取得 = APIコール実施 resp.contents.each{ |obj| puts c[:key] } end
last_page?とnext_pageを利用しました。意味は名前を見ると通じるかと思いますが、last_page?はこれが最後の取得出来るリソースかどうかを判定し、next_pageで次の10個のリソースを取得しています。これ以上取得できるリソースがない状態でnext_pageを実行すると、LastPageErrorが発生するので注意しましょう。
また、each_pageという、全ページを順番に取得して処理を実施するメソッドも用意されています。全リソースに対して必ず処理を実施する場合はかなり便利だと思います。上の例は、以下の様に書きなおすことが出来ます。
require 'aws-sdk-core' s3 = Aws::S3::Client.new s3.list_objects(bucket: 'mochizuki-bucket', max_keys: "10").each_page do |resp| puts resp.contents.map{ |obj| obj[:key] } end
だいぶ記述がすっきりしました!
Waiters
AWSのAPIは、基本的にあるリクエストに対するレスポンスを即座に返しますが、そのリクエストで意図した結果が必ず起こるとは限らない、というところには注意が必要です。例えばstart-instancesというAPIは、Stop状態のEC2インスタンスを起動するためのAPIです。APIリクエストに成功すると、HTTPコード200 とともにインスタンスの情報が返ってきます。ですが、HTTP 200を受け取ったからといって、このインスタンスがrunningになるとは限りません。例えば起動処理中にAWSのデータセンターに隕石が落ちてDCが破損した場合(参考)、そのEC2の最終的な状態は保証できません。
何が言いたいかというと、APIレスポンスが返ってきた後、その対象が望むべきStatusになっているかどうかを暫くの間監視しておく必要があるのです。
これを普通にやろうとすると、APIリクエスト後、定期的にdescribe-instanceを叩いてStatusの値をチェックして、何回以内に成功しなければ異常と判断されるので例外を投げる、、等、だいぶ面倒なのですが、SDK v2では各サービスのクライアントクラスにwait_untilというメソッドが追加され、このあたりの制御が簡単に行えるようになりました。コードを見てみましょう。
require 'aws-sdk-core' ec2 = Aws::EC2::Client.new begin ec2.start_instances(instance_ids: ['i-1234567']) ec2.wait_until(:instance_running, instance_ids:['i-1234567']) puts "instance running" rescue Aws::Waiters::Errors::WaiterFailed => error puts "failed waiting for instance running: #{error.message}" end
start-instancesを実行した後、7行目のwait_untilの部分でステータスのポーリングを実施し、ステータスがinstance_runningになるまで監視してくれます。ただし、一定期間内にステータスが想定のステータスにならなかった場合、例外となります。
以下のように記述することで、監視のインターバルや最大リトライ数を調整することもできます。
require 'aws-sdk-core' ec2 = Aws::EC2::Client.new begin ec2.start_instances(instance_ids: ['i-1234567']) ec2.wait_until(:instance_running, instance_ids:['i-1234567']) do |waiter| waiter.interval = 5 # number of seconds to sleep between attempts waiter.max_attempts = 1 # maximum number of polling attempts end puts "instance running" rescue Aws::Waiters::Errors::WaiterFailed => error puts "failed waiting for instance running: #{error.message}" end
対話型コンソール
SDK v2のgemに付随して、aws.rbというコマンドもついてきます。これはirbやpryといった対話型コンソールで、手元で簡単にSDKの動きを確認したい時に使えます。
...と思ったら、SDK v1にもaws-rbというのがありました。(このブログを書いていて初めて知りました。。。)
SDK v1との相違点
SDK v2のREADMEにも記載されていますが、セマンティックバージョニングを採用しているので、メジャーバージョンアップには互換性のない変更も含まれます。
上のコードを見ていて気づかれた方もいるかと思いますが、SDK v1とv2では名前空間が異なります。SDK v1ではAWSモジュールに含まれていましたが、SDK v2ではAwsモジュールとなります。大文字小文字に注意しましょう。
また、SDK v1で利用していたAPIの高度なラッパークラスであるResourceクラス(AWS::EC2::Instances等)は、SDK v2の2014/09/26時点ではexperimentalとされています。さらに、aws-sdk-resourcesという別のGemに切り出されたようなので、利用する際には十分に注意しましょう。追加でインストールする場合には、gemコマンドを使ってインストールします。
$ gem install aws-sdk-resources
まとめ
Githubの履歴を見ていたら、SDK v2のrc1がリリースされたのが昨年の11月ということで、最初のrcから1年弱が経過して、ようやく正式版リリースとなりました。まだまだ開発途中の機能もあるようですが、興味のある方は使ってみてはいかがでしょうか。